package chen.web.config.spring;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import chen.web.config.AccountTableConfig;
import chen.web.config.ConfigRepository;
import chen.web.config.IpTableConfig;
import chen.web.config.UuidTableConfig;
import chen.web.firewall.AbstractTable.Type;
import chen.web.firewall.AccountTable;
import chen.web.firewall.IpSegment;
import chen.web.firewall.IpTable;
import chen.web.firewall.UuidTable;
import chen.web.user.Account;
import chen.web.user.AccountManager;

@Configuration
public class FireWallConfig {

	private @Autowired AccountManager accountManager;
	
	public @Bean IpTable ipTable(){
		IpTableConfig config = ConfigRepository.instance().get(IpTableConfig.class);
		IpTable ipTable = new IpTable();
		Set<String> segments = config.getSegments(Type.Allow);
		for(String segment : segments){
			ipTable.addRule(IpSegment.parse(segment), Type.Allow);
		}
		segments = config.getSegments(Type.Deny);
		for(String segment : segments){
			ipTable.addRule(IpSegment.parse(segment), Type.Deny);
		}	
		return ipTable;
	}
	
	public @Bean UuidTable uuidTable(){
		UuidTableConfig config = ConfigRepository.instance().get(UuidTableConfig.class);
		UuidTable table = new UuidTable();
		Set<String> uuids = config.getUuids(Type.Allow);
		for(String uuid : uuids){
			table.addRule(uuid, Type.Allow);
		}
		uuids = config.getUuids(Type.Deny);
		for(String uuid : uuids){
			table.addRule(uuid, Type.Deny);
		}
		return table;
	}
	
	public @Bean AccountTable accountTable(){
		AccountTableConfig config = ConfigRepository.instance().get(AccountTableConfig.class);
		AccountTable table = new AccountTable();
		Set<Integer> ids = config.getIds(Type.Allow);
		List<Integer> intIds = toList(ids);
		List<Account> accountList = accountManager.getAccount(intIds);
		for(Account acc : accountList){
			table.addRule(acc, Type.Allow);
		}
		ids = config.getIds(Type.Deny);
		intIds = toList(ids);
		accountList = accountManager.getAccount(intIds);
		for(Account acc : accountList){
			table.addRule(acc, Type.Deny);
		}
		return table;
	}
	
	private List<Integer> toList(Set<Integer> set){
		List<Integer> list = new ArrayList<Integer>(set.size());
		for(Integer i : set){
			list.add(i);
		}
		return list;
	}
}
